from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm, SetPasswordForm
from django.contrib.auth import login, authenticate, logout, update_session_auth_hash
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.contrib.admin.views.decorators import staff_member_required
from django import forms
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_exempt
from django.db.models import Q
from django.core.paginator import Paginator
from django.utils import timezone
from .models import UserProfile, CheckIn, UserMessage, Achievement, UserAchievement, Task, UserTask, ExpLog, TemporaryPassword, FeatureSwitch
from battles.models import Battle, BattleStatistics
import json

# 用户表单，用于编辑基本信息
class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email')
        labels = {
            'username': '用户名',
            'first_name': '名',
            'last_name': '姓',
            'email': '电子邮箱',
        }

# 个人资料表单，用于编辑额外信息
class ProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('bio', 'location', 'birth_date', 'avatar')
        widgets = {
            'birth_date': forms.DateInput(attrs={'type': 'date'}),
        }

def login_view(request):
    """用户登录视图"""
    # 检查登录注册控制开关
    if FeatureSwitch.is_feature_enabled('login_registration_control'):
        # 如果开关启用，检查是否为admin用户
        if request.method == 'POST':
            form = AuthenticationForm(request, data=request.POST)
            if form.is_valid():
                username = form.cleaned_data.get('username')
                password = form.cleaned_data.get('password')
                user = authenticate(username=username, password=password)
                if user is not None:
                    # 只允许admin用户登录
                    if user.is_staff or user.is_superuser:
                        login(request, user)
                        messages.success(request, f'欢迎回来，{username}！')
                        return redirect('home')
                    else:
                        messages.error(request, FeatureSwitch.get_disabled_message('login_registration_control'))
                        return render(request, 'accounts/login.html', {'form': form})
            else:
                messages.error(request, '用户名或密码错误！')
        else:
            form = AuthenticationForm()
            # 显示系统维护提示
            messages.warning(request, FeatureSwitch.get_disabled_message('login_registration_control'))
        return render(request, 'accounts/login.html', {'form': form})
    
    # 正常登录流程
    if request.method == 'POST':
        form = AuthenticationForm(request, data=request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            user = authenticate(username=username, password=password)
            if user is not None:
                login(request, user)
                messages.success(request, f'欢迎回来，{username}！')
                return redirect('home')
        else:
            messages.error(request, '用户名或密码错误！')
    else:
        form = AuthenticationForm()
    return render(request, 'accounts/login.html', {'form': form})

def logout_view(request):
    """用户登出视图"""
    logout(request)
    messages.success(request, '您已成功登出！')
    return redirect('home')

def signup(request):
    """用户注册视图"""
    # 检查登录注册控制开关
    if FeatureSwitch.is_feature_enabled('login_registration_control'):
        # 如果开关启用，禁止用户注册
        messages.error(request, FeatureSwitch.get_disabled_message('login_registration_control'))
        return redirect('accounts:login')  # 重定向到登录页面
    
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            user = form.save()
            username = form.cleaned_data.get('username')
            messages.success(request, f'账户 {username} 创建成功！')
            login(request, user)  # 注册后自动登录
            return redirect('home')  # 重定向到首页
    else:
        form = UserCreationForm()
    return render(request, 'accounts/signup.html', {'form': form})

@login_required
def profile_view(request):
    """查看用户个人资料"""
    user = request.user
    # 确保用户有profile对象
    try:
        profile = user.profile
    except UserProfile.DoesNotExist:
        # 如果用户没有profile，创建一个
        profile = UserProfile(user=user)
        profile.save()
    return render(request, 'accounts/profile.html', {'user': user})

@login_required
def edit_profile(request):
    """编辑用户个人资料"""
    # 确保用户有profile对象
    try:
        profile = request.user.profile
    except UserProfile.DoesNotExist:
        # 如果用户没有profile，创建一个
        profile = UserProfile(user=request.user)
        profile.save()

    if request.method == 'POST':
        user_form = UserForm(request.POST, instance=request.user)
        profile_form = ProfileForm(request.POST, request.FILES, instance=profile)

        if user_form.is_valid() and profile_form.is_valid():
            user_form.save()
            profile_form.save()
            messages.success(request, '个人资料更新成功！')
            return redirect('accounts:profile')
    else:
        user_form = UserForm(instance=request.user)
        profile_form = ProfileForm(instance=profile)

    return render(request, 'accounts/edit_profile.html', {
        'user_form': user_form,
        'profile_form': profile_form
    })

@login_required
def change_password(request):
    """修改密码视图"""
    from django.contrib.auth.forms import PasswordChangeForm
    from django.contrib.auth import update_session_auth_hash

    if request.method == 'POST':
        form = PasswordChangeForm(request.user, request.POST)
        if form.is_valid():
            user = form.save()
            # 更新会话，防止密码更改后用户被登出
            update_session_auth_hash(request, user)
            messages.success(request, '密码修改成功！')
            return redirect('accounts:profile')
    else:
        form = PasswordChangeForm(request.user)

    return render(request, 'accounts/change_password.html', {'form': form})


@login_required
def personal_space(request, user_id=None):
    """个人空间视图"""
    if user_id:
        target_user = get_object_or_404(User, id=user_id)
    else:
        target_user = request.user
    
    # 确保用户有profile对象
    try:
        profile = target_user.profile
    except UserProfile.DoesNotExist:
        profile = UserProfile(user=target_user)
        profile.save()
    
    # 获取用户统计信息
    try:
        battle_stats = target_user.battle_stats
    except BattleStatistics.DoesNotExist:
        battle_stats = None
    
    # 获取最近的战斗记录
    recent_battles = Battle.objects.filter(
        Q(player1=target_user) | Q(player2=target_user)
    ).order_by('-created_at')[:5]
    
    # 获取用户成就
    user_achievements = UserAchievement.objects.filter(
        user=target_user
    ).select_related('achievement').order_by('-achieved_at')[:6]
    
    # 获取经验值日志
    exp_logs = ExpLog.objects.filter(
        user=target_user
    ).order_by('-created_at')[:10]
    
    # 获取留言（如果是查看自己的空间）
    messages_received = []
    if target_user == request.user:
        messages_received = UserMessage.objects.filter(
            to_user=target_user
        ).select_related('from_user').order_by('-created_at')[:5]
    
    # 获取签到状态
    checkin_status = CheckIn.get_user_checkin_status(target_user)
    
    context = {
        'target_user': target_user,
        'profile': profile,
        'battle_stats': battle_stats,
        'recent_battles': recent_battles,
        'user_achievements': user_achievements,
        'exp_logs': exp_logs,
        'messages_received': messages_received,
        'checkin_status': checkin_status,
        'is_own_space': target_user == request.user,
    }
    
    return render(request, 'accounts/personal_space.html', context)


@login_required
@require_POST
def check_in(request):
    """签到API"""
    try:
        checkin, message = CheckIn.check_in_today(request.user)
        if checkin:
            return JsonResponse({
                'success': True,
                'message': message,
                'exp_reward': checkin.exp_reward,
                'consecutive_days': checkin.consecutive_days,
                'new_level': request.user.profile.level,
                'new_exp': request.user.profile.exp,
            })
        else:
            return JsonResponse({
                'success': False,
                'message': message
            })
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'签到失败: {str(e)}'
        })


@login_required
def achievement_list(request):
    """成就列表页面"""
    # 获取所有成就
    all_achievements = Achievement.objects.filter(is_active=True).order_by('achievement_type', 'created_at')
    
    # 获取用户已获得的成就
    user_achievements = UserAchievement.objects.filter(
        user=request.user
    ).values_list('achievement_id', flat=True)
    
    # 按类型分组成就
    achievements_by_type = {}
    for achievement in all_achievements:
        if achievement.achievement_type not in achievements_by_type:
            achievements_by_type[achievement.achievement_type] = []
        
        achievement.is_achieved = achievement.id in user_achievements
        achievements_by_type[achievement.achievement_type].append(achievement)
    
    context = {
        'achievements_by_type': achievements_by_type,
        'total_achievements': all_achievements.count(),
        'achieved_count': len(user_achievements),
    }
    
    return render(request, 'accounts/achievements.html', context)


@login_required
def send_message(request, user_id):
    """发送留言"""
    target_user = get_object_or_404(User, id=user_id)
    
    if request.method == 'POST':
        content = request.POST.get('content', '').strip()
        if content:
            UserMessage.objects.create(
                from_user=request.user,
                to_user=target_user,
                content=content
            )
            messages.success(request, '留言发送成功！')
        else:
            messages.error(request, '留言内容不能为空！')
    
    return redirect('accounts:personal_space', user_id=user_id)


@login_required
def api_user_stats(request, user_id=None):
    """获取用户统计数据API"""
    if user_id:
        user = get_object_or_404(User, id=user_id)
    else:
        user = request.user
    
    try:
        battle_stats = user.battle_stats
        stats_data = {
            'total_battles': battle_stats.total_battles,
            'wins': battle_stats.wins,
            'losses': battle_stats.losses,
            'draws': battle_stats.draws,
            'win_rate': round(battle_stats.wins / max(battle_stats.total_battles, 1) * 100, 1),
            'rating': battle_stats.rating,
            'current_rank': battle_stats.current_rank,
        }
    except BattleStatistics.DoesNotExist:
        stats_data = {
            'total_battles': 0,
            'wins': 0,
            'losses': 0,
            'draws': 0,
            'win_rate': 0,
            'rating': 0,
            'current_rank': '未排名',
        }
    
    return JsonResponse({
        'success': True,
        'stats': stats_data,
        'level': user.profile.level,
        'exp': user.profile.exp,
        'total_exp': user.profile.total_exp,
        'next_level_exp': user.profile.next_level_exp(),
        'exp_percentage': user.profile.exp_percentage(),
    })


@login_required
def api_recent_battles(request, user_id=None):
    """获取最近战斗记录API"""
    if user_id:
        user = get_object_or_404(User, id=user_id)
    else:
        user = request.user
    
    battles = Battle.objects.filter(
        Q(player1=user) | Q(player2=user)
    ).order_by('-created_at')[:10]
    
    battles_data = []
    for battle in battles:
        opponent = battle.player2 if battle.player1 == user else battle.player1
        result = 'unknown'
        if battle.status == 'finished' and battle.result:
            if battle.result == 'draw':
                result = 'draw'
            elif (battle.result == 'player1_wins' and battle.player1 == user) or \
                 (battle.result == 'player2_wins' and battle.player2 == user):
                result = 'win'
            else:
                result = 'loss'
        
        battles_data.append({
            'id': battle.id,
            'opponent': opponent.username,
            'result': result,
            'status': battle.status,
            'created_at': battle.created_at.strftime('%Y-%m-%d %H:%M'),
            'battle_type': battle.battle_type,
        })
    
    return JsonResponse({
        'success': True,
        'battles': battles_data
    })


@staff_member_required
def admin_reset_password(request, user_id):
    """管理员重置用户密码"""
    target_user = get_object_or_404(User, id=user_id)
    
    if request.method == 'POST':
        # 生成临时密码
        temp_pwd = TemporaryPassword.generate_temp_password(
            user=target_user,
            created_by=request.user,
            hours=24  # 24小时有效期
        )
        
        messages.success(
            request, 
            f'用户 {target_user.username} 的密码已重置。临时密码：{temp_pwd.temp_password}（24小时内有效）'
        )
        
        # 重定向回用户管理页面
        return redirect('admin:auth_user_changelist')
    
    return render(request, 'accounts/admin_reset_password.html', {
        'target_user': target_user
    })


@login_required
def force_change_password(request):
    """强制修改密码（使用临时密码登录后）"""
    # 检查用户是否有有效的临时密码
    temp_password = TemporaryPassword.objects.filter(
        user=request.user,
        is_used=False,
        expires_at__gt=timezone.now()
    ).first()
    
    if not temp_password:
        # 如果没有临时密码，重定向到普通密码修改页面
        return redirect('accounts:change_password')
    
    if request.method == 'POST':
        form = SetPasswordForm(request.user, request.POST)
        if form.is_valid():
            user = form.save()
            # 标记临时密码为已使用
            temp_password.mark_as_used()
            
            # 更新会话，防止密码更改后用户被登出
            update_session_auth_hash(request, user)
            
            messages.success(request, '密码修改成功！您现在可以正常使用系统了。')
            return redirect('home')
    else:
        form = SetPasswordForm(request.user)
    
    return render(request, 'accounts/force_change_password.html', {
        'form': form,
        'temp_password': temp_password
    })


@login_required
def temp_password_login_view(request):
    """临时密码登录后的提示页面"""
    temp_password = TemporaryPassword.objects.filter(
        user=request.user,
        is_used=False,
        expires_at__gt=timezone.now()
    ).first()
    
    if not temp_password:
        return redirect('home')
    
    return render(request, 'accounts/temp_password_notice.html', {
        'temp_password': temp_password
    })


@staff_member_required
def admin_feature_switches(request):
    """管理员功能开关管理页面"""
    switches = FeatureSwitch.objects.all().order_by('switch_key')
    
    # 为功能开关添加描述信息
    switch_descriptions = {
        'code_operations': '控制用户是否可以进行代码相关操作（创建、编辑、删除代码）',
        'battle_creation': '控制用户是否可以创建对战（包括练习赛、匹配赛等）',
        'user_registration': '控制是否允许新用户注册账号',
        'api_access': '控制是否允许通过API访问系统功能',
        'private_code_challenge': '控制是否允许挑战和匹配他人的私有代码（不包括星标代码，星标代码默认可挑战）',
        'login_registration_control': '控制登录和注册功能，启用时仅允许管理员用户登录和注册，普通用户将被禁止访问',
    }
    
    # 为每个开关添加描述
    for switch in switches:
        switch.description = switch_descriptions.get(switch.switch_key, '暂无描述')
    
    return render(request, 'accounts/admin_feature_switches.html', {
        'switches': switches
    })


@staff_member_required
@require_POST
@csrf_exempt
def admin_toggle_feature_switch(request, switch_id):
    """切换功能开关状态"""
    try:
        switch = get_object_or_404(FeatureSwitch, id=switch_id)
        switch.is_enabled = not switch.is_enabled
        switch.save()
        
        return JsonResponse({
            'success': True,
            'is_enabled': switch.is_enabled,
            'message': f'功能开关 "{switch.get_switch_key_display()}" 已{"启用" if switch.is_enabled else "禁用"}'
        })
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'操作失败: {str(e)}'
        }, status=500)
